package com.ocean.web.controller.business;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.InputStreamResource;
import com.ocean.business.domain.DownTotalDo;
import com.ocean.business.domain.ProductReportDo;
import com.ocean.business.domain.UploadingTotalDo;
import com.ocean.business.domain.query.DownTotalQuery;
import com.ocean.business.domain.query.UploadStatisticsParticularsQuery;
import com.ocean.business.mapper.BusinessStatisticsMapper;
import com.ocean.business.service.IBusinessStatisticsService;
import com.ocean.common.annotation.Log;
import com.ocean.common.core.controller.BaseController;
import com.ocean.common.core.domain.AjaxResult;
import com.ocean.common.core.page.TableDataInfo;
import com.ocean.common.enums.BusinessType;
import com.ocean.common.utils.poi.ExcelUtil;
import com.ocean.common.utils.security.PermissionUtils;
import com.ocean.inxex.domain.SysFtpConfig;
import com.ocean.inxex.domain.SysFtpLog;
import com.ocean.productDict.domain.oNcfileMonitor;
import com.ocean.system.domain.ODownwebDwon;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @Author: FuGui Wang
 * @Description: TODO 后台系统-统计管理-前端控制器
 * @Date 2022/12/5
 * @Version V1.1.0
 */
@Slf4j
@Controller
@RequestMapping("/statistics")
public class BusinessStatisticsControlController extends BaseController {

    private String prefix = "business/statistics";

    @Autowired
    private IBusinessStatisticsService statisticsService;
    @Autowired
    private BusinessStatisticsMapper statisticsMapper;
    /**
     * 按下载量统计 页面跳转
     */
    @RequiresPermissions("statistics:download:view")
    @GetMapping("/download")
    @ApiOperation(value = "统计管理-按下载量统计-页面跳转")
    public String toDownloadStatistics(){
        return prefix + "/downStatisticsTime";
    }

    /**
     * 统计管理-按下载量统计列表
     * @param query 检索条件
     * @return 数据集合
     */
    @RequiresPermissions("statistics:download:list")
    @PostMapping("/selectDownloadStatisticsList")
    @ResponseBody
    @ApiOperation(value = "统计管理-按下载量统计列表")
    public TableDataInfo selectDownloadStatisticsList(DownTotalQuery query) {
        startPage();
        List<DownTotalDo> list = statisticsService.selectDownloadStatisticsList(query);
        return getDataTable(list);
    }

    /**
     * 统计总个数
     * @param query
     * @return
     */
    @PostMapping("/selectDownloadStatisticsListzs")
    @ResponseBody
    public AjaxResult selectDownloadStatisticsListz() {
        DownTotalQuery query = new DownTotalQuery();
        List<DownTotalDo> list = statisticsService.selectDownloadStatisticsList(query);//总个数
        Integer zh = 0;
        for (int i = 0; i < list.size(); i++) {
            zh += list.get(i).getDownValue();
        }
        List<Double>  zsize= statisticsService.getzsize();//总大小 M
        Double zhsize = 0.0;
        for (int i = 0; i < zsize.size(); i++) {
            if(zsize.get(i)!=null){
                zhsize += zsize.get(i);
            }
        }
        Map map = new HashMap();
        map.put("zh",zh);
        map.put("zhsize",convertMBtoGB(zhsize));
        return AjaxResult.success(map);
    }

    /**
     * M转G
     * @param mb
     * @return
     */
    public static String convertMBtoGB(double mb) {
        // 1. 转换为 GB（1 GB = 1024 MB）
        BigDecimal gb = BigDecimal.valueOf(mb / 1024.0);

        // 2. 四舍五入保留两位小数
        gb = gb.setScale(2, RoundingMode.HALF_UP);

        // 3. 格式化输出
        return gb.stripTrailingZeros().toPlainString() + " GB";
    }
    /**
     * 产品上传统计 页面跳转
     */
    @RequiresPermissions("statistics:uploading:view")
    @GetMapping("/uploading")
    public String toUploadingStatistics(){
        return prefix + "/uploadingStatisticsTime";
    }

    /**
     * 统计管理-产品上传统计列表
     * @param query 检索条件
     * @return 数据集合
     */
    @RequiresPermissions("statistics:uploading:list")
    @PostMapping("/selectUploadingStatisticsList")
    @ResponseBody
    @ApiOperation(value = "统计管理-产品上传统计列表")
    public TableDataInfo selectUploadingStatisticsList(DownTotalQuery query) {
        int num = statisticsService.selectnum(query);//总数量
        startPage();
        List<UploadingTotalDo> list = statisticsService.selectUploadingStatisticsList(query);
        //返回数据
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(0);
        rspData.setRows(list);
        rspData.setTotal(num);
        return rspData;
    }

    /**
     * 导出年报
     * @return
     * @throws Exception
     */
    @GetMapping("/download-modified-word")
    public void downloadModifiedWord(HttpServletResponse response) throws Exception {
        // 设置替换参数
        Map<String, String> replacements = new HashMap<>();
        // 读取模板文件
        ClassPathResource templateResource = new ClassPathResource("templates/NBMB.docx");
        List<UploadingTotalDo> list = new LinkedList<>();
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 构造年初日期 (1月1日)
        LocalDate startOfYear = currentDate.withDayOfYear(1);
        // 构造年末日期 (12月31日)
        LocalDate endOfYear = currentDate.withDayOfYear(currentDate.lengthOfYear());
        // 定义日期格式 (yyyyMMdd)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 格式化并输出结果
        System.out.println("年初日期: " + startOfYear.format(formatter));  // 如 20250101
        System.out.println("年末日期: " + endOfYear.format(formatter));    // 如 20251231
        DownTotalQuery query = new DownTotalQuery();
        // 查询产品列表
        List<UploadingTotalDo> uploadingTotalDos = statisticsMapper.selecplist(query);
        String beginTime = (startOfYear.format(formatter));
        String endTime = (endOfYear.format(formatter));

        int j = 0;
        for (UploadingTotalDo uploadingTotalDo : uploadingTotalDos) {//普通产品
            long l = dateDifferenceInDays(startOfYear.format(formatter), endOfYear.format(formatter));
            long ts = 0;
            long bfb = 0;
            int num1 = statisticsMapper.selenum(uploadingTotalDo.getId(), "1", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());//数量查询要根据query里的参数进行查询
            int num2 = statisticsMapper.selenum(uploadingTotalDo.getId(), "2", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());//单位
            int num0 = statisticsMapper.selenum(uploadingTotalDo.getId(), "0", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());
            uploadingTotalDo.setShouldUpload(uploadingTotalDo.getFrequency());//应上传(值为每天应上传几个 03 是两个 其他是1个)
            uploadingTotalDo.setRealityUpload(num1 + num2);//实上传
            uploadingTotalDo.setNormalUpload(num1);//正常上传
            uploadingTotalDo.setLateUpload(num2);//晚传上传
            uploadingTotalDo.setLeakUpload(num0);//异常上传
            if(uploadingTotalDo.getShouldUpload().equals("03")){
                ts = l * 2;
            }else{
                ts = l;
            }
            int i = num1 + num2;
            if(i!=0){
                bfb = (long)calculatePercentage(ts,i);
            }else{
                bfb = 0;
            }
            // 定义格式模式：强制两位小数
            DecimalFormat df = new DecimalFormat("#0.00");
            replacements.put("${"+uploadingTotalDo.getId()+"}", df.format(bfb)+"%");
        }
        //智能网格
        List<oNcfileMonitor> hmf = statisticsMapper.getsj("海面风");
        List<oNcfileMonitor> hl = statisticsMapper.getsj("海浪");
        List<oNcfileMonitor> hliu = statisticsMapper.getsj("海流");
        List<oNcfileMonitor> bwd = statisticsMapper.getsj("海表面温度");
        List<oNcfileMonitor> hb = statisticsMapper.getsj("海冰");
        // 定义格式模式：强制两位小数
        DecimalFormat df = new DecimalFormat("#0.00");
        replacements.put("${hmf}", df.format(calculatePercentage(9125,hmf.size()))+"%");
        replacements.put("${hl}", df.format(calculatePercentage(9125,hliu.size()))+"%");
        replacements.put("${hliu}", df.format(calculatePercentage(9125,hliu.size()))+"%");
        replacements.put("${bwd}", df.format(calculatePercentage(9125,bwd.size()))+"%");
        replacements.put("${hb}", df.format(calculatePercentage(9125,hb.size()))+"%");

        int year = LocalDate.now().getYear(); // 直接获取当前年份
        replacements.put("${nf}", String.valueOf(year));//年份
        List<ODownwebDwon> xzsl = statisticsMapper.getxzsl();
        double size = 0.0;
        for (int i = 0; i < xzsl.size(); i++) {
            if(xzsl.get(i)!=null){
                size +=xzsl.get(i).getSize();
            }
        }
        double gb = mbToGb(size);  // 输出 2.0 GB下载大小
        replacements.put("${1}", String.valueOf(year));
        replacements.put("${2}", String.valueOf(year));//年份1和2
        replacements.put("${num}", String.valueOf(xzsl.size()));//下载此时


        List<SysFtpLog> tssj = statisticsMapper.gettssj();//推送数据
        List<SysFtpConfig> tsyh = statisticsMapper.gettsyhsj();//推送用户数量
        double tssize = 0.0;
        for (int i = 0; i < tssj.size(); i++) {
            if(tssj.get(i).getSize()!=null){
                tssize += tssj.get(i).getSize();
            }
        }
        double v = mbToGb(mbToGb(tssize));//推送大小
        replacements.put("${dx}", String.format("%.2f GB", gb));// 下载量
        replacements.put("${user}", String.valueOf(tsyh.size())); // 推送用户数
        replacements.put("${tsl}", String.format("%.2f GB", v)); // 推送量
        replacements.put("${cs}", String.valueOf(tssj.size())); // 推送次数
        replacements.put("${yhs}", String.valueOf(tsyh.size())); // 用户数

        replacements.put("${name}", "111");
        replacements.put("${age}", "222");

        // 生成替换后的文件
        byte[] processedWord = statisticsService.replacePlaceholders(templateResource.getStream(), replacements);

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.setHeader("Content-Disposition", "attachment; filename=" +
                URLEncoder.encode("年报.docx", StandardCharsets.UTF_8));

        // 输出文件
        response.getOutputStream().write(processedWord);
    }


    /*@GetMapping("/download-modified-word")
    public ResponseEntity<byte[]> downloadModifiedWord() throws Exception {

        // 读取模板文件
        ClassPathResource templateResource = new ClassPathResource("templates/NBMB.docx");
        try (InputStream is = templateResource.getStream();
             XWPFDocument doc = new XWPFDocument(is)) {

                List<UploadingTotalDo> list = new LinkedList<>();
                // 获取当前日期
                LocalDate currentDate = LocalDate.now();
                // 构造年初日期 (1月1日)
                LocalDate startOfYear = currentDate.withDayOfYear(1);
                // 构造年末日期 (12月31日)
                LocalDate endOfYear = currentDate.withDayOfYear(currentDate.lengthOfYear());
                // 定义日期格式 (yyyyMMdd)
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                // 格式化并输出结果
                System.out.println("年初日期: " + startOfYear.format(formatter));  // 如 20250101
                System.out.println("年末日期: " + endOfYear.format(formatter));    // 如 20251231
                DownTotalQuery query = new DownTotalQuery();
                // 查询产品列表
                List<UploadingTotalDo> uploadingTotalDos = statisticsMapper.selecplist(query);
                String beginTime = (startOfYear.format(formatter));
                String endTime = (endOfYear.format(formatter));
                //循环产品列表
                int j = 0;
                for (UploadingTotalDo uploadingTotalDo : uploadingTotalDos) {//普通产品
                    long l = dateDifferenceInDays(startOfYear.format(formatter), endOfYear.format(formatter));
                    long ts = 0;
                    long bfb = 0;
                    int num1 = statisticsMapper.selenum(uploadingTotalDo.getId(), "1", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());//数量查询要根据query里的参数进行查询
                    int num2 = statisticsMapper.selenum(uploadingTotalDo.getId(), "2", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());//单位
                    *//*int num3 = statisticsMapper.selenum(uploadingTotalDo.getId(),"3");*//*
                    int num0 = statisticsMapper.selenum(uploadingTotalDo.getId(), "0", uploadingTotalDo.getProductName(), beginTime, endTime, uploadingTotalDo.getDeptName());
                    uploadingTotalDo.setShouldUpload(uploadingTotalDo.getFrequency());//应上传(值为每天应上传几个 03 是两个 其他是1个)
                    uploadingTotalDo.setRealityUpload(num1 + num2);//实上传
                    uploadingTotalDo.setNormalUpload(num1);//正常上传
                    uploadingTotalDo.setLateUpload(num2);//晚传上传
                    *//*uploadingTotalDo.setRepairUpload(num3);//补传上传*//*
                    uploadingTotalDo.setLeakUpload(num0);//异常上传
                    if(uploadingTotalDo.getShouldUpload().equals("03")){
                        ts = l * 2;
                    }else{
                        ts = l;
                    }
                    int i = num1 + num2;
                    if(i!=0){
                        bfb = (long)calculatePercentage(ts,i);
                    }else{
                        bfb = 0;
                    }
                    // 定义格式模式：强制两位小数
                    DecimalFormat df = new DecimalFormat("#0.00");
                    replacePlaceholder(doc,uploadingTotalDo.getId(), df.format(bfb)+"%");
                    System.out.println(j++);
                }
                //智能网格
                List<oNcfileMonitor> hmf = statisticsMapper.getsj("海面风");
                List<oNcfileMonitor> hl = statisticsMapper.getsj("海浪");
                List<oNcfileMonitor> hliu = statisticsMapper.getsj("海流");
                List<oNcfileMonitor> bwd = statisticsMapper.getsj("海表面温度");
                List<oNcfileMonitor> hb = statisticsMapper.getsj("海冰");
                // 定义格式模式：强制两位小数
                DecimalFormat df = new DecimalFormat("#0.00");
                replacePlaceholder(doc,"hmf", df.format(hmf.size())+"%");
                replacePlaceholder(doc,"hl", df.format(hl.size())+"%");
                replacePlaceholder(doc,"hliu", df.format(hliu.size())+"%");
                replacePlaceholder(doc,"bwd", df.format(bwd.size())+"%");
                replacePlaceholder(doc,"hb", df.format(hb.size())+"%");
            // 设置替换参数
            Map<String, String> replacements = new HashMap<>();
            int year = LocalDate.now().getYear(); // 直接获取当前年份
            replacements.put("${nf}", String.valueOf(year));//年份
            List<ODownwebDwon> xzsl = statisticsMapper.getxzsl();
            double size = 0.0;
            for (int i = 0; i < xzsl.size(); i++) {
                if(xzsl.get(i)!=null){
                    size +=xzsl.get(i).getSize();
                }
            }
            double gb = mbToGb(size);  // 输出 2.0 GB下载大小
            replacements.put("${1}", String.valueOf(year));
            replacements.put("${2}", String.valueOf(year));//年份1和2
            replacements.put("${num}", String.valueOf(xzsl.size()));//下载此时


            List<SysFtpLog> tssj = statisticsMapper.gettssj();//推送数据
            List<SysFtpConfig> tsyh = statisticsMapper.gettsyhsj();//推送用户数量
            double tssize = 0.0;
            for (int i = 0; i < tssj.size(); i++) {
                if(tssj.get(i).getSize()!=null){
                    tssize += tssj.get(i).getSize();
                }
            }
            double v = mbToGb(mbToGb(tssize));//推送大小
            replacements.put("{dx}", String.format("%.2f GB", gb));// 下载量
            replacements.put("{user}", String.valueOf(tsyh.size())); // 推送用户数
            replacements.put("{tsl}", String.format("%.2f GB", v)); // 推送量
            replacements.put("{cs}", String.valueOf(tssj.size())); // 推送次数
            replacements.put("{yhs}", String.valueOf(tsyh.size())); // 用户数
            // 生成替换后的文件
            ByteArrayOutputStream processedWord = replacePlaceholders(is, replacements);
            // 遍历段落替换 ${name}
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
                String text = paragraph.getText();
               *//* if (text.contains("${nf}")) {
                    int year = LocalDate.now().getYear(); // 直接获取当前年份
                    text = text.replace("${nf}", String.valueOf(year)); // 年份
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*


             *//*   if (text.contains("${num}")) {
                    text = text.replace("${num}", String.valueOf(xzsl.size())); // 下载此时
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
               *//* if (text.contains("${1}")) {
                    int year = LocalDate.now().getYear(); // 直接获取当前年份
                    text = text.replace("${nf1}", String.valueOf(year)); // 年份
                    text = text.replace("${num}", String.valueOf(xzsl.size())); // 下载此时
                    paragraph.getRuns().get(0).setText(text, 0);
                }
                if (text.contains("${2}")) {
                    int year = LocalDate.now().getYear(); // 直接获取当前年份
                    text = text.replace("${nf2}", String.valueOf(year)); // 年份
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*

              *//*  List<SysFtpLog> tssj = statisticsMapper.gettssj();//推送数据
                List<SysFtpConfig> tsyh = statisticsMapper.gettsyhsj();//推送用户数量
                double tssize = 0.0;
                for (int i = 0; i < tssj.size(); i++) {
                    if(tssj.get(i).getSize()!=null){
                        tssize += tssj.get(i).getSize();
                    }
                }
                double v = mbToGb(mbToGb(tssize));//推送大小
                if (text.contains("${dx}")) {
                    text = text.replace("${dx}", String.format("%.2f GB", gb)); // 下载量
                    text = text.replace("${user}", String.valueOf(tsyh.size())); // 推送用户数
                    text = text.replace("${tsl}", String.format("%.2f GB", v)); // 推送量
                    text = text.replace("${cs}", String.valueOf(tssj.size())); // 推送次数
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
               *//* if (text.contains("${user}")) {
                    text = text.replace("${user}", String.valueOf(tsyh.size())); // 推送用户数
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
             *//*   if (text.contains("${cs}")) {
                    text = text.replace("${cs}", String.valueOf(tssj.size())); // 推送次数
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
             *//*   if (text.contains("${tsl}")) {
                    text = text.replace("${tsl}", String.format("%.2f GB", v)); // 推送量
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
               *//* if (text.contains("${yhs}")) {
                    text = text.replace("${yhs}", String.valueOf(tsyh.size())); // 用户数
                    paragraph.getRuns().get(0).setText(text, 0);
                }*//*
            }

            // 生成字节数组
          *//*  ByteArrayOutputStream bos = new ByteArrayOutputStream();
            doc.write(bos);
*//*
            // 设置响应头
            String fileName = URLEncoder.encode("modified-report.docx", "UTF-8")
                    .replace("+", "%20");
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", fileName);

            return ResponseEntity.ok()
                    .headers(headers)
                    .body(processedWord.toByteArray());
        }
    }
*/
    public ByteArrayOutputStream replacePlaceholders(InputStream inputStream, Map<String, String> replacements) throws IOException, IOException {
        try (XWPFDocument document = new XWPFDocument(inputStream)) {
            // 替换正文中的占位符
            replaceInParagraphs(document.getParagraphs(), replacements);

            // 替换表格中的占位符
            for (XWPFTable table : document.getTables()) {
                for (XWPFTableRow row : table.getRows()) {
                    for (XWPFTableCell cell : row.getTableCells()) {
                        replaceInParagraphs(cell.getParagraphs(), replacements);
                    }
                }
            }

            // 替换页眉中的占位符
            for (XWPFHeader header : document.getHeaderList()) {
                replaceInParagraphs(header.getParagraphs(), replacements);
            }

            // 替换页脚中的占位符
            for (XWPFFooter footer : document.getFooterList()) {
                replaceInParagraphs(footer.getParagraphs(), replacements);
            }

            // 保存到字节数组
            try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                document.write(out);
                return out;
            }
        }
    }

    private void replaceInParagraphs(List<XWPFParagraph> paragraphs, Map<String, String> replacements) {
        for (XWPFParagraph paragraph : paragraphs) {
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : replacements.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            text = text.replace(entry.getKey(), entry.getValue());
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }
    public static double mbToGb(double mb) {
        return mb / 1024.0;  // 1 GB = 1024 MB:ml-citation{ref="5" data="citationList"}
    }

    // 示例
    public static void main(String[] args) {
        double v = calculatePercentage(751, 4);
        System.out.println(v);
    }
    /**
     * 计算第二个数是第一个数的百分比
     * @param base 第一个参数（基数）
     * @param value 第二个参数（目标值）
     * @return 百分比数值（例如 25.0 表示 25%）
     * @throws IllegalArgumentException 如果基数为零
     */
    public static double calculatePercentage(double base, double value) {
        if (base == 0) {
            throw new IllegalArgumentException("基数（第一个参数）不能为零");
        }
        return (value / base) * 100;
    }
    public XWPFDocument replacePlaceholder(XWPFDocument doc,String id, String name) {
        // 遍历所有表格
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    // 替换单元格中的占位符
                    String text = cell.getText();
                    if (text.contains("${"+id+"}")) {
                        text = text.replace("${"+id+"}", name);
                        cell.removeParagraph(0);  // 清空原内容
                        cell.setText(text);
                    }
                }
            }
        }
        return doc;
    }
    public static long dateDifferenceInDays(String date1Str, String date2Str) {
        try {
            // 解析日期字符串（格式必须为 yyyy-MM-dd）
            DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
            LocalDate date1 = LocalDate.parse(date1Str, formatter);
            LocalDate date2 = LocalDate.parse(date2Str, formatter);

            // 计算绝对值天数差
            return Math.abs(ChronoUnit.DAYS.between(date1, date2));
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("Invalid date format. Expected yyyy-MM-dd.");
        }
    }
    /**
     * 统计管理-导出统计
     */
    @Log(title = "产品上传报告统计", businessType = BusinessType.EXPORT)
    @RequiresPermissions("statistics:uploading:export-statistics")
    @PostMapping("/exportStatistics")
    @ResponseBody
    @ApiOperation(value = "统计管理-导出统计")
    public AjaxResult exportStatistics(DownTotalQuery query) {
        List<UploadingTotalDo> uploadingTotalDos = statisticsService.selectUploadingStatisticsList(query);
        ExcelUtil<UploadingTotalDo> util = new ExcelUtil<>(UploadingTotalDo.class);

        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodedBytes = decoder.decode(PermissionUtils.getPrincipalProperty("userName").toString());
        String decodedString = new String(decodedBytes);
        return util.exportExcel(uploadingTotalDos, "产品上传报告统计","导出人:" + decodedString);
    }

    /**
     * 统计管理-导出详情
     */
    @Log(title = "产品上传报告详情", businessType = BusinessType.EXPORT)
    @RequiresPermissions("statistics:uploading:export-particulars")
    @PostMapping("/exportParticulars")
    @ResponseBody
    @ApiOperation(value = "统计管理-导出详情")
    public AjaxResult exportParticulars(DownTotalQuery query) {
        List<ProductReportDo> uploadingTotalDos = statisticsService.selectUploadingParticularsList(query);
        ExcelUtil<ProductReportDo> util = new ExcelUtil<>(ProductReportDo.class);

        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decodedBytes = decoder.decode(PermissionUtils.getPrincipalProperty("userName").toString());
        String decodedString = new String(decodedBytes);

        return util.exportExcel(uploadingTotalDos, "产品上传报告详情","导出人:" + decodedString);
    }

    /**
     * 统计管理-查看详情
     */
    @Log(title = "统计管理-查看详情", businessType = BusinessType.EXPORT)
    @RequiresPermissions("statistics:uploading:view-particulars")
    @GetMapping("/viewParticulars/{id}/{startTime}/{endTime}")
//    @ResponseBody
    @ApiOperation(value = "统计管理-查看详情")
    public String viewParticulars(@PathVariable String id,@PathVariable String startTime,@PathVariable String endTime, UploadStatisticsParticularsQuery query, ModelMap mmap) {
        query.setId(id);
        Map<String, Object> map = query.getParams();
        if (!map.containsKey("beginTime")) map.put("beginTime",startTime);
        if (!map.containsKey("endTime")) map.put("endTime",endTime);
        mmap.put("query",query);
        /*mmap.put("startTime",startTime);
        mmap.put("endTime",endTime);*/
        return prefix + "/uploadingStatisticsTimeDetail";
    }
    @PostMapping("/detail")
    @ResponseBody
    @ApiOperation(value = "统计管理-产品上传统计列表")
    public TableDataInfo detail(@RequestParam String id, UploadStatisticsParticularsQuery query) {
        query.setId(id);
        startPage();
        List<ProductReportDo> uploadingTotalDos = statisticsService.viewParticulars(query);
        return getDataTable(uploadingTotalDos);
    }

}
